import 'dart:math';

import 'package:flutter/material.dart';

class PaintEditorPage extends StatelessWidget {
  const PaintEditorPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Paint Editor'),
      ),
      body: PaintBody(),
    );
  }
}

class PaintBody extends StatefulWidget {
  const PaintBody({super.key});

  @override
  State<PaintBody> createState() => _PaintBodyState();
}

class _PaintBodyState extends State<PaintBody> {
  double _scaleFactor = 1;
  double _initialDistance = 0;
  Offset _initialPointerDownPosition = Offset.zero;

  double _scale = 1;
  Offset _offset = Offset.zero;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
        onScaleStart: (details) {
          _initialPointerDownPosition = details.focalPoint;
          _initialDistance = details.localFocalPoint.distance;
        },
        onScaleUpdate: (details) {
          setState(() {
            final currentDistance = details.scale;
            _scaleFactor *= currentDistance / _initialDistance;
            _initialDistance = currentDistance;
            _scaleFactor = (_scaleFactor < 0.1) ? 0.1 : _scaleFactor;
            _scaleFactor = (_scaleFactor > 2.0) ? 2.0 : _scaleFactor;
            _scale *= details.scale;
            _offset = Offset(_offset.dx + details.focalPointDelta.dx,
                _offset.dy + details.focalPointDelta.dy);
          });
        },
        child: Container(
            width: double.infinity,
            height: double.infinity,
            child: CustomPaint(
              size: Size.infinite,
              painter: PaintEditor(_scaleFactor, _scale, _offset),
            )));
  }
}

class PaintEditor extends CustomPainter {
  double _scaleFactor;
  double _scale = 1;
  Offset _offset;
  PaintEditor(this._scaleFactor, this._scale, this._offset);
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.red
      ..strokeWidth = 1;

    const double barWidth = 20;
    final double boardWidth = size.width - barWidth;

    // X
    final xScale = 300 / boardWidth;
    for (int i = 0; i < 300; i += 10) {
      final xPosition = i / xScale;
      double dy = 14;
      if (i % 100 == 0) {
        dy = 0;
        _drawText(canvas, '${i}', Offset(xPosition + 2 + barWidth, 0));
      }
      canvas.drawLine(Offset(xPosition + barWidth, dy),
          Offset(xPosition + barWidth, 20), paint);
    }
    // 绘制X轴刻度尺的背景色和下边框
    final xBackgroundPaint = Paint()
      ..color = Colors.grey.withOpacity(0.2)
      ..style = PaintingStyle.fill;
    final xBorderPaint = Paint()
      ..color = Colors.grey
      ..strokeWidth = 1.0
      ..style = PaintingStyle.stroke;
    canvas.drawRect(
      Rect.fromLTWH(0, 0, size.width, 20),
      xBackgroundPaint,
    );
    canvas.drawLine(
      Offset(0, 20),
      Offset(size.width, 20),
      xBorderPaint,
    );

    // Y
    for (int i = 0; i < (size.height - barWidth); i += 10) {
      final yPosition = i / xScale;
      double dx = 14;
      if (i % 100 == 0) {
        dx = 0;
        _drawText(
            canvas, i.toString(), Offset(0, yPosition + barWidth + 6), -90);
      }
      canvas.drawLine(Offset(dx, yPosition + barWidth),
          Offset(20, yPosition + barWidth), paint);
    }
    // 绘制Y轴刻度尺的背景色和右边框
    final yBackgroundPaint = Paint()
      ..color = Colors.grey.withOpacity(0.2)
      ..style = PaintingStyle.fill;
    final yBorderPaint = Paint()
      ..color = Colors.grey
      ..strokeWidth = 1.0
      ..style = PaintingStyle.stroke;
    canvas.drawRect(
      Rect.fromLTWH(0, 0, 20, size.height),
      yBackgroundPaint,
    );
    canvas.drawLine(
      Offset(20, 0),
      Offset(20, size.height),
      yBorderPaint,
    );

    // 绘制主背景色
    final mainBoardPaint = Paint()..color = Colors.grey.withOpacity(.3);
    canvas.drawRect(
      Rect.fromLTWH(barWidth, barWidth, boardWidth, size.height - barWidth),
      mainBoardPaint,
    );

    // 绘制网格背景色
    final boardPaint = Paint()..color = Colors.white;
    canvas.drawRect(
      Rect.fromLTWH(barWidth, barWidth, boardWidth, boardWidth),
      boardPaint,
    );

    // 绘制网格
    final gridPaint = Paint()
      ..color = Colors.grey.withOpacity(.4)
      ..strokeWidth = 1;
    for (int i = 0; i <= 300; i += 10) {
      print(_scale);
      final xPosition = (i / xScale) * _scale + barWidth;
      canvas.drawLine(Offset(xPosition, barWidth),
          Offset(xPosition, (boardWidth + barWidth)), gridPaint);
    }
    for (int i = 0; i <= 300; i += 10) {
      final yPosition = i / xScale * _scale + barWidth;
      canvas.drawLine(Offset(barWidth, yPosition),
          Offset(boardWidth + barWidth, yPosition), gridPaint);
    }
  }

  // 绘制文字
  void _drawText(Canvas canvas, String text, Offset offset,
      [double? rotation]) {
    final textPainter = TextPainter(
      text: TextSpan(
        text: text,
        style: TextStyle(
          color: Colors.black,
          fontSize: 12,
        ),
      ),
      textDirection: TextDirection.ltr,
    )..layout();
    canvas.save();
    if (rotation != null) {
      final rotationCenter = Offset(offset.dx + textPainter.width / 2,
          offset.dy + textPainter.height / 2);

      canvas.translate(rotationCenter.dx, rotationCenter.dy);
      canvas.rotate(-90.0 * (pi / 180)); // 逆时针旋转90度
      canvas.translate(-rotationCenter.dx, -rotationCenter.dy);
    }
    textPainter.paint(canvas, offset);
    canvas.restore();
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
  }
}
